package com.drawm.adt.pseudoCodeEditor {
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.HTTPStatusEvent;
	import flash.events.ErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.display.Loader;
	import flash.text.StyleSheet;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;

	/**
	 * @author Drawm
	 */
	public class Model extends EventDispatcher {
		
//		DATA -------------------------------------------------------------------------------------------//
//		PUBLIC / STATIC DATA ----------------------------------------------------------------------//
		public static const STOP_APP        : String = "STOP";
		public static const START_APP      : String = "START";
		public static const RESET_TEXT     : String = "RESET_TEXT";
		public static const UPDATE_STYLE : String = "UPDATE_STYLE";
		
		public static var appWidth    : int = 450;
		public static var appHeight   : int = 565;
		public static var styleSheet  : StyleSheet;
		private static var _htmlText    : String;
		
		
		private static var _keywords:Vector.<String>;
		
		
		public static function get htmlText():String {
			return Model._htmlText;
		}
		public static function set htmlText(text:String):void {
			Model._htmlText = text;
		}
		
		
//		PRIVATE DATA ------------------------------------------------------------------------------//
		private static var styleURL : String = "css/style.css";
		private var _styleSheet:StyleSheet = new StyleSheet();
		
//		Keyword bank - Need to be loaded and parsed from a .css file before use
		private var _keywordBank:Vector.<String>;

		public function Model(target : IEventDispatcher = null) {
			super(target);
		}

		public function start() : void {
			loadCSS();
			
			Model.styleSheet = new StyleSheet();
			
			dispatchEvent(new Event(START_APP));
			
			Model.htmlText = "<body> New Session</body>";
		}

		private function loadCSS() : void {
			
//			Start loading CSS
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, onLoadCSSComplete);
			
			loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
			loader.addEventListener(Event.INIT, initHandler);
			loader.addEventListener(IOErrorEvent.IO_ERROR, IOErrorHandler); // the one i needed
			loader.addEventListener(Event.OPEN, openHandler);
			loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			loader.addEventListener(Event.UNLOAD, unLoadHandler);

			loader.load(new URLRequest(Model.styleURL));
		}

		private function initHandler(event : Event) : void {
			trace("initHandler");
			addToHtmlText("<span class='consoleerrormsg'>"+event+" : AS BEEN INIT "+"</span>");
		}
		private function httpStatusHandler(event : HTTPStatusEvent) : void {
			trace("httpStatusHandler");
			addToHtmlText("<span class='consoleerrormsg'>"+event.status+" - "+event.type+"</span>");
			
		}
		private function IOErrorHandler(event : IOErrorEvent) : void {
			trace("IOErrorHandler");
			addToHtmlText("<span class='consoleerrormsg'>"+event.text+" - "+event.type+"</span>");
			
		}
		private function openHandler(event : Event) : void {
			trace("openHandler");
		}
		private function progressHandler(event : ProgressEvent) : void {
			trace("progressHandler");
			
		}
		private function unLoadHandler(event : Event) : void {
			trace("unLoadHandler");
			
		}
		
		private function addToHtmlText(text:String):void{
			Model.htmlText = "<body>"+text+"</body>";
			dispatchEvent(new Event(Model.RESET_TEXT));
		}


		
		private function onLoadCSSComplete(event : Event) : void {
			
			
			event.target.removeEventListener(Event.COMPLETE,onLoadCSSComplete);
			var css:String = event.target.data;
			
			
//			Save the new CSS
			Model.styleSheet.parseCSS(css);
			dispatchEvent(new Event(Model.UPDATE_STYLE));
			
//			Parse keyword bank
			parseCSSToKeyword(css);
			
//			Parse view's htmltext
			parseHTMLText(css);
			
			addToHtmlText("CSS FULLY LOADED - STARTING PARCING = <div class='consoleerrormsg'> "+ event.target.data+"</div>");
			
		}

		private function parseCSSToKeyword(css : String) : void {
//			Get every tag used in this css and put them in the keyword bank
			 Model._keywords = new Vector.<String>();
			var endIndex:int;
			var newString:String;
			var threshold:int = 0;
			while(css.indexOf("{") != -1 || threshold >= 250){
				endIndex = css.indexOf("{");
				newString = css.slice(0,endIndex);
				css = css.slice(endIndex+1,-1);
				
				while(newString.substr(newString.length-1,1) == " ")
					newString = newString.slice(0,newString.length-1);
					
				if(newString.lastIndexOf(".") != -1)
					_keywords.push(newString.slice(newString.lastIndexOf(".")+1,newString.length));
				
				
				threshold++;
			}
			trace("threshold = "+threshold);
			trace("KEYWORD = "+Model._keywords);
		}
		
		
		private function parseHTMLText(data : String) : void {
//			Parse view's htmltext - Add tag to match user's text
			
			var newString:String = "";
			var breakableData:String = "";

			for (var i:String in Model._keywords) {
				
				var keyword:String = Model._keywords[i];
				
				trace("\nDEBUG THAT BITCH -----------------------------------------------------------------\n");
				
				trace(" - compare = " + keyword.charAt(0) +" from " + keyword+" in "+data);
				
				trace(" - keyword = " + keyword);
				breakableData = data;
				var checker:int = 0;
				while (checker != -1){
				
					checker = data.indexOf(keyword.charAt(0)) ;
					
					trace(" - checker = " + checker);
					
					if (checker != -1) {
						var backIsClear:Boolean = false;
						var frontIsClear:Boolean = false;
						
						if (checker != 1) {
//							var authorizeChar:Vector.<String>= Vector.<String>(["	","","\n"," ","{","}","(",")",".",",","=","+","-","*","-","<",">","%","&","|",":",";"]);
							var authorizeChar:Array= ["	","","\n"," ","{","}","(",")",".",",","=","+","-","*","-","<",">","%","&","|",":",";"];
							for (var j:String in authorizeChar) {
								if (data.charAt(checker - 1) == authorizeChar[j])
									backIsClear = true;
								if (data.charAt(checker + keyword.length) == authorizeChar[j])
									frontIsClear = true;
									
								trace("back / front check = BASIC: '" + authorizeChar[j] + "' data.b: '" +  data.charAt(checker - 1) + "' = '" + (data.charAt(checker - 1) == authorizeChar[j]) + "' || data.f: '" + data.charAt(checker + keyword.length) + "'  = '" + (data.charAt(checker + keyword.length) == authorizeChar[j]))+"'";
							
							}
								trace("REPORT :: backIsClear = " + backIsClear + " & frontIsClear = " + frontIsClear);
							if (backIsClear && frontIsClear) {
								
								trace("ARE THEY EQUAL ? = '"+ keyword +"' == '"+data.substr(checker, keyword.length)+"'");
								
								if (keyword == data.substr(checker, keyword.length)) {
									
									trace("newString = "+data.substr(0, checker) +" + <span class="+keyword + "'>|" + data.substr(checker, keyword.length) + "|</span>");
									
									breakableData += data.substr(0, checker) + "<span class='" + keyword + "'>|" + data.substr(checker, keyword.length) + "|</span>";
									data = data.substring(checker + keyword.length, data.length -1);
								}else	{
									newString += data.substr(0, checker + 1);
									data = data.substring(checker + 1, data.length -1);
								}
								// FIX : à chaque fin de boule for(i), il faut reconstruire le data avec les span déja intégré;
								data = newString;
							}
						}
					}
					
					
				}
			}
			
			Model.htmlText = "<body>"+data+"</body>";
			trace("\n-----------------------------------------------------------------");
			trace("DEBUG ENDED -----------------------------------------------------------------");
			trace("data = " + data);
			
//			Reset htmltext
			dispatchEvent(new Event(RESET_TEXT));
		}

//		GET & SET ---------------------------------------------------------------------------------//
		public function get styleSheet():StyleSheet{
			return _styleSheet;
		}
	}
}
